import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:pp_uikit/pp_group/pp_group_util.dart';
import 'package:pp_uikit/theme/pp_default_theme.dart';
import 'package:pp_uikit/theme/pp_group_theme.dart';

///
/// 文本块输入型录入项
///
/// 包括"标题"、"副标题"、"必填项提示"、"文本输入框"等元素
///
// ignore: must_be_immutable
class PPGroupBlockInput extends StatefulWidget {
  /// 录入项标题
  final String? title;

  /// 录入项子标题
  final String? subTitle;

  /// 输入框的初始值，默认为""
  final String contentText;

  /// 录入项是否为必填项（展示*图标） 默认为 false 不必填
  final bool isRequire;

  /// 录入项 是否可编辑
  final bool isEdit;

  /// 输入字符数上限
  final int? maxLength;

  /// 是否显示输入字数指示器
  final bool showNumberIndicator;

  /// 录入项 hint 提示
  final String hint;

  /// 输入内容类型
  final TextInputType? inputType;

  /// 是否自动获取焦点
  bool autofocus;

  /// 指定对输入数据的格式化要求
  final List<TextInputFormatter>? inputFormatters;

  /// 输入回调
  final ValueChanged<String>? onChanged;

  /// 点击确定后的回调
  final ValueChanged<String>? onSubmitted;

  /// 用于对 TextField  更精细的控制，若传入该字段，[contentText] 参数将失效，可使用 TextEditingController.text 进行赋值。
  final TextEditingController? controller;

  /// 最小行数，默认值4
  final int? minLines;

  /// 最大行数，默认值20
  final int? maxLines;

  /// 背景色
  final Color? backgroundColor;

  /// form配置
  PPGroupTheme? themeData;

  PPGroupBlockInput(
      {Key? key,
      this.title,
      this.subTitle,
      this.contentText = "",
      this.isEdit = true,
      this.isRequire = false,
      this.onChanged,
      this.onSubmitted,
      this.hint = "请输入",
      this.maxLength,
      this.showNumberIndicator = true,
      this.autofocus = false,
      this.inputType,
      this.inputFormatters,
      this.controller,
      this.minLines = 4,
      this.maxLines = 20,
      this.backgroundColor,
      this.themeData})
      : super(key: key) {
    themeData ??= PPGroupTheme();
  }

  @override
  PPGroupBlockInputState createState() {
    return PPGroupBlockInputState();
  }
}

class PPGroupBlockInputState extends State<PPGroupBlockInput> {
  late TextEditingController _controller;

  @override
  void initState() {
    String textData = widget.contentText;
    if (widget.maxLength != null &&
        widget.contentText.runes.length > widget.maxLength!) {
      var sRunes = textData.runes;
      textData = String.fromCharCodes(sRunes, 0, widget.maxLength);
    }
    var tmpController = widget.controller;
    if (tmpController == null) {
      if (textData.isNotEmpty) {
        tmpController = TextEditingController.fromValue(TextEditingValue(
            text: textData,
            selection: TextSelection.fromPosition(TextPosition(
                affinity: TextAffinity.downstream, offset: textData.length))));
      } else {
        tmpController = TextEditingController();
      }
    }
    _controller = tmpController;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: widget.backgroundColor ?? widget.themeData!.backgroundColor,
      padding: const EdgeInsets.only(bottom: 10),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          if (widget.title != null)
            ConstrainedBox(
              constraints: const BoxConstraints(
                minHeight: 40,
              ),
              child: Row(
                children: <Widget>[
                  // 是否必填图标
                  PPGroupUtil.buildRequireWidget(widget.isRequire),

                  // title
                  PPGroupUtil.buildTitleWidget(widget.title,
                      style: widget.themeData?.titleTextStyle),

                  PPGroupUtil.buildSubLabelWidget(widget.subTitle),
                ],
              ),
            ),

          // 输入框
          Container(
            padding: const EdgeInsets.all(10),
            decoration: BoxDecoration(
              color: widget.backgroundColor ??
                  PPDefaultTheme.instance.backgroundColor,
              borderRadius: const BorderRadius.all(Radius.circular(4)),
            ),
            child: TextField(
              autofocus: widget.autofocus,
              keyboardType: widget.inputType,
              controller: _controller,
              maxLength: widget.maxLength,
              maxLengthEnforcement:
                  MaxLengthEnforcement.truncateAfterCompositionEnds,
              maxLines: widget.maxLines,
              minLines: widget.minLines,
              textAlign: TextAlign.left,
              enabled: widget.isEdit,
              style: _textStyle(),
              inputFormatters: widget.inputFormatters,
              decoration: InputDecoration(
                hintText: widget.hint,
                hintStyle: widget.themeData?.hintTextStyle,
                contentPadding: const EdgeInsets.all(0),
                border: InputBorder.none,
                isDense: true,
                enabledBorder: const UnderlineInputBorder(
                    borderSide: BorderSide(color: Colors.transparent)),
                focusedBorder: const UnderlineInputBorder(
                    borderSide: BorderSide(color: Colors.transparent)),
              ),
              onChanged: widget.onChanged,
              onSubmitted: widget.onSubmitted,
              buildCounter: _buildCounter(),
            ),
          )
        ],
      ),
    );
  }

  TextStyle _textStyle() {
    if (widget.isEdit) {
      return widget.themeData!.editTextStyle;
    }
    return widget.themeData!.editDisableTextStyle;
  }

  InputCounterWidgetBuilder? _buildCounter() {
    if (widget.maxLength == null) {
      return null;
    }
    return (context, {required currentLength, required isFocused, maxLength}) {
      return widget.showNumberIndicator
          ? Row(
              mainAxisAlignment: MainAxisAlignment.end,
              children: <Widget>[
                Text(
                  "$currentLength",
                  style: widget.themeData?.hintTextStyle,
                ),
                Text(
                  "/$maxLength",
                  style: widget.themeData?.hintTextStyle,
                ),
              ],
            )
          : null;
    };
  }

  @override
  void dispose() {
    super.dispose();
    if (widget.controller == null) {
      _controller.dispose();
    }
  }
}
